package com.auxgroup.smarthome.utils;

import com.auxgroup.smarthome.regex.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigInteger;

/**
 * Created by kevinchen on 2017/9/4.
 */
public class ProtocolConvertUtils {


    /**
     * 16进制字符串转成二进制字符串
     * @param hexString
     * @return 二进制字符串
     */
    public static String hexString2binaryString(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0)
            return null;
        String bString = "", tmp;
        for (int i = 0; i < hexString.length(); i++) {
            tmp = "0000"
                    + Integer.toBinaryString(Integer.parseInt(hexString
                    .substring(i, i + 1), 16));
            bString += tmp.substring(tmp.length() - 4);
        }
        return bString;
    }

    /**
     * 二进制字符串转16进制
     * @param bString
     * @return
     */
    public static String binaryString2hexString(String bString) {
        if (bString == null || bString.equals("") || bString.length() % 8 != 0)
            return null;
        StringBuffer tmp = new StringBuffer();
        int iTmp = 0;
        for (int i = 0; i < bString.length(); i += 4) {
            iTmp = 0;
            for (int j = 0; j < 4; j++) {
                iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
            }
            tmp.append(Integer.toHexString(iTmp));
        }
        return tmp.toString();
    }

    /**
     * 2位长度的16进字符串转十进制
     * @param hexStr 2位长度的16进字符串
     * @return
     */
    public static Integer convert2HexStrToDecimal(String hexStr){
        if (hexStr == null || hexStr.length() != 2 ){
            throw new IllegalArgumentException();
        }
        String num = Integer.valueOf(hexStr,16).toString();
        return Integer.parseInt(num);
    }

    /**
     * 不大于255的10进制转2位长度的16进制字符串
     * @param decNum
     * @return
     */
    public static String converDecimalto2HexStr(Integer decNum){
        if (decNum > 0xff){
            throw new IllegalArgumentException("该十进制数大于255！");
        }
        String hexString = Integer.toHexString(decNum);
        if (hexString.length()<2){
            return "0"+hexString;
        }
        return hexString;
    }

    /**
     * 不大于255的10进制转4位长度的16进制字符串
     * @param decNum
     * @return
     */
    public static String converDecimalto4HexStr(Integer decNum){
        if (decNum > 0xff){
            throw new IllegalArgumentException("该十进制数大于255！");
        }
        String hexStr = converDecimalto2HexStr(decNum);
        if (hexStr.length()<4){
            return hexStr + "00";
        }
        return hexStr;
    }

    /**
     * 2进制的转10进制
     * @param binaryStr
     * @return
     */
    public static Integer change2To10(String binaryStr){
        if(binaryStr == null || binaryStr.isEmpty())
            return null;
        int x = 0;
        for(char c: binaryStr.toCharArray())
            x = x * 2 + (c == '1' ? 1 : 0);
        return x;
    }


    /**
     * 二进制字符串转换为byte数组,每个字节以","隔开
     * @param binarystr
     * @return
     */
    public static byte[] convertBinaryToBytes(String binarystr) {
        String [] temp = binarystr.split(",");
        byte [] b = new byte[temp.length];
        for(int i = 0;i<b.length;i++) {
            b[i] = Long.valueOf(temp[i], 2).byteValue();
        }
        return b;
    }

    /**
     * 8位长度的二进制字符串 转换为 byte
     * @param binaryStr 8位长度的二进制字符串
     * @return
     */
    public static byte convertSingleBinaryToByte(String binaryStr){
        if ( StringUtils.isBlank(binaryStr) ||
                binaryStr.length() != 8 ){
            throw new IllegalArgumentException();
        }
        return Long.valueOf(binaryStr, 2).byteValue();
    }

    /**
     * 二进制字符串转两位16进制字符串
     * @param binaryStr
     * @return
     */
    public static String converBinaryto2HexStr(String binaryStr){
        if ( StringUtils.isBlank(binaryStr) ||
                binaryStr.length() != 8 ){
            throw new IllegalArgumentException();
        }
        int intValue = Long.valueOf(binaryStr, 2).intValue();
        if (intValue > 0xff){
            throw new IllegalArgumentException();
        }
        String hexString = Integer.toHexString(intValue);
        if (hexString.length() < 2){
            hexString = '0'+hexString;
        }
        return hexString;
    }


    /**
     * byte数组转换为十六进制的字符串
     * @param b
     * @return
     */
    public static String conver16HexStr(byte [] b) {
        StringBuffer result = new StringBuffer();
        for(int i = 0;i<b.length;i++) {
            if((b[i]&0xff)<0x10)
                result.append("0");
            result.append(Long.toString(b[i]&0xff, 16));
        }
        return result.toString().toUpperCase();
    }

    /**
     * 十六进制的字符串转换为byte数组
     * @param hex16Str
     * @return
     */
    public static byte[] conver16HexToByte(String hex16Str) {
        char [] c = hex16Str.toCharArray();
        byte [] b = new byte[c.length/2];
        for(int i = 0;i<b.length;i++) {
            int pos = i * 2;
            b[i] = (byte)("0123456789ABCDEF".indexOf(c[pos]) << 4
                    | "0123456789ABCDEF".indexOf(c[pos+1]));
        }
        return b;
    }

    /**
     * 字节数组转多进制
     * @param bytes
     * @param radix 指定某进制数
     * @return
     */
    public static String binary(byte[] bytes, int radix){
        if (radix <  Character.MIN_RADIX || radix > Character.MAX_RADIX){
            radix = 0x0a;
        }
        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
    }


    /**
     * 获取十进制数 转 指定长度二进制字符串
     * @param value   十进制数
     * @param offset  偏移量
     * @param length  二进制字符串保留长度
     * @return
     */
    public static String toBinaryString(int value, int offset, int length){
        String binaryString = Integer.toBinaryString(value-offset);
        char[] chars = binaryString.toCharArray();
        int len = chars.length;
        int j = length -len;
        char[] totalChars = new char[length];
        for (int i = 0; i < length; i++) {
            if (i < j){
                totalChars[i]= '0';
            }else{
                totalChars[i]= chars[i-j];
            }
        }
        return String.valueOf(totalChars);
    }

    /**
     * 字符串转换成十六进制字符串
     * @param  str 待转换的ASCII字符串
     * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
     */
    public static String str2HexStr(String str) {

        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;

        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            sb.append(' ');
        }
        return sb.toString().trim();
    }

    /**
     * 十六进制转换字符串
     * @param  hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
     * @return String 对应的字符串
     */
    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }

    /**
     * bytes转换成十六进制字符串
     * @param  b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte[] b) {
        String stmp="";
        StringBuilder sb = new StringBuilder("");
        for (int n=0;n<b.length;n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length()==1)? "0"+stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }


    /**
     * 偶数位字符的16进制字符串 一半位高位字符与一半低位字符互换
     * @param hexStr 0123 ==>2301
     * @return
     */
    public static String highConvertLowHexStr(String hexStr){
        if (!ValidatorUtils.isHexStr(hexStr) || hexStr.length()%2 != 0 ){
            throw new IllegalArgumentException();
        }
        char[] charArray = hexStr.toCharArray();
        char[] tempArr = new char[charArray.length];
        int half = charArray.length/2;
        for (int i = charArray.length - 1; i >= 0 ; i--) {
            if (i >= half){
                tempArr[i-half] = charArray[i];
            }else{
                tempArr[i+half] = charArray[i];
            }
        }
        return String.valueOf(tempArr);
    }



    /**
     * 16进字符串转十进制
     * @param hexStr 16进字符串
     * @return
     */
    public static Integer hexStrConvertDecimal(String hexStr){
        if (!ValidatorUtils.isHexStr(hexStr)){
            throw new IllegalArgumentException();
        }
        String num = Integer.valueOf(hexStr,16).toString();
        return Integer.parseInt(num);
    }

    /**
     * 从低位开始截取16进制字符串
     * @param hexStr
     * @param backLength 截取的长度
     * @return
     */
    public static String substringHexStr(String hexStr,int backLength){
        if (!ValidatorUtils.isHexStr(hexStr)){
            throw new IllegalArgumentException();
        }
        char[] charArray = hexStr.toCharArray();
        char[] tempArr = new char[backLength];
        for (int i = charArray.length - backLength; i < charArray.length ; i++) {
            tempArr[i - ( charArray.length - backLength )] = charArray[i];
        }
        return String.valueOf(tempArr);
    }

    /**
     * {"01","01","C0","00","00","20","00","80","00","00","22","00","10","07"};
     * 转成
     * [0101, C000, 0020, 0080, 0000, 2200, 1007]
     * @param dataStr DATA的2位十六进制字符串数组
     * @return  DATA的4位十六进制字符串数组
     */
    public static String[] constructData4HexStrArr(String[] dataStr ){
        StringBuffer temp =new StringBuffer();
        int totalLength = dataStr.length % 2 == 0 ? dataStr.length/2 : (dataStr.length/2) + 1;
        String[] resultArr = new String[totalLength];
        int count = 0;
        for (int i = 0; i < dataStr.length; i++) {
            if (i%2==0){
                temp.append(dataStr[i]);
            }
            if (i%2==1){
                temp.append(dataStr[i]);
                resultArr[count] = temp.toString();
                temp = new StringBuffer();
                count++;
            }
        }
        if (count == totalLength - 1){
            temp.append("00");
            resultArr[count] = temp.toString();
        }
        return resultArr;
    }

    /**
     * FCC的校验码的4位16进制转成 2个长度的十进制数组
     * @param hexStr
     * @return
     */
    public static int[] getFccNumArr(String hexStr){
        if (!ValidatorUtils.isHex4Str(hexStr)){
            throw new IllegalArgumentException();
        }
        char[] charArray = hexStr.toCharArray();
        char[] hex1Arr = new char[2];
        char[] hex2Arr = new char[2];
        for (int i = 0; i < 4; i++) {
            if (i <=1){
                hex1Arr[i] = charArray[i];
            }
            if (i>1){
                hex2Arr[i-2] = charArray[i];
            }
        }
        String hex1Str = String.valueOf(hex1Arr);
        int hexNum1 = ProtocolConvertUtils.convert2HexStrToDecimal(hex1Str);
        String hex2Str = String.valueOf(hex2Arr);
        int hexNum2 = ProtocolConvertUtils.convert2HexStrToDecimal(hex2Str);
        return new int[]{hexNum1,hexNum2};
    }

    /**
     * 每两位16进制转成10进制数组，1个数组占一个byte字节
     * @param hexStr 16进制字符串，必须为偶数
     * @return
     */
    public static int[] hexStr2IntArray(String hexStr) {
        int length = hexStr.length();
        if(length % 2 != 0) throw new IllegalArgumentException("16进制字符串非法");
        int[] raw = new int[length/2];
        int initRaw = 0;
        char[] hexChar = hexStr.toCharArray();
        for (int i = 0; i < length; i+=2) {
            char[] decChar = new char[2];
            decChar[0] = hexChar[i];
            decChar[1] = hexChar[i+1];
            int decimal = Integer.valueOf(String.valueOf(decChar),16);
            raw[initRaw] = decimal;
            initRaw++;
        }
        return raw;
    }

}
